home *** CD-ROM | disk | FTP | other *** search
/ Developer CD Series 1997 April: Mac OS SDK / Dev.CD Apr 97 SDK1.toast / Development Kits (Disc 1) / PC Card Manager / CustomEnabler / CustomEnabler.c next >
Encoding:
Text File  |  1997-01-13  |  10.5 KB  |  347 lines  |  [TEXT/CWIE]

  1. //    ----------------------------------------------------------------------
  2. //
  3. //    Module:
  4. //        CustomEnabler.c
  5. //
  6. //    Purpose:
  7. //        SystemSoft custom enabler to support multiple cards
  8. //
  9. //    Authors:
  10. //        Andrew Dallas
  11. //        Dave Tarabar
  12. //
  13. //    Copyright:    © 1996 SystemSoft Corporation, all rights reserved.
  14. //    ----------------------------------------------------------------------
  15.  
  16. #include <DriverSupport.h>
  17. #include <Errors.h>
  18. #include <PCCardEnablerPlugin.h>
  19. #include <PCCardTuples.h>
  20.  
  21. //#define DEBUG_ON 1
  22. #ifdef DEBUG_ON
  23. #define DebugMessage(x) SysBreakStr(x)
  24. #else
  25. #define DebugMessage(x)
  26. #endif
  27.  
  28. //----------------------------------------------------------------------
  29. // list of supported card's MANFID tuple (in Intel Byte order)
  30.  
  31. // Dayna "CommuniCard E" EtherNet Adapter P/N 98056-01
  32. #define kDaynaManfID        0x0194002D
  33. // Megahertz Gold Series 14.4 Fax Modem
  34. #define kMegahertzManfID    0x02010500
  35.  
  36. typedef enum {
  37.     kUnsupportedCardID                    = 0,
  38.     kDaynaCommunicardEthernetAdapter,
  39.     kMegahertzGoldSeries14_4FaxModem
  40.  
  41. } SupportedCardID, *SupportedCardIDPtr;
  42.  
  43. SupportedCardID gThisCardID = kUnsupportedCardID;
  44.  
  45. //----------------------------------------------------------------------
  46. //    Local Prototypes
  47. OSStatus MyValidateHardware(const RegEntryRef * lpCardEntry);
  48. OSStatus MyGetDeviceCount(const RegEntryRef * lpParentID,UInt32 *lpCount);
  49. OSStatus MyGetDeviceType(const RegEntryRef * lpDevice,UInt32 socket,UInt32 device,PCDeviceType *lpDeviceType);
  50. OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device, PCCardTupleIterator lpTupleIterator,
  51.             Byte desiredTuple, void *lptupleData, UInt32 *lpTupleBufferSize, Byte *lpFoundTuple);
  52.  
  53. OSStatus _IdentifyCard(const RegEntryRef *    lpCardEntry, SupportedCardIDPtr lpCardType);
  54. Boolean CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName);
  55.  
  56. //----------------------------------------------------------------------
  57. // Globals
  58.  
  59. #define kVersionMajor        1
  60. #define kVersionMinor        0
  61. #define kVersionStage        developStage
  62. #define kVersionNonRel        1
  63. #define kPluginNamePString    "\pSuperPCCardEnabler"
  64.  
  65. #pragma export on 
  66.  
  67. // --------------------
  68. // Here's the exported Driver Descriptor
  69. DriverDescription TheDriverDescription = {
  70.     /*
  71.      * Signature info
  72.      */
  73.     kTheDescriptionSignature,                /* OSType driverDescSignature            */
  74.     kInitialDriverDescriptor,                /* DriverDescVersion driverDescVersion    */
  75.     /*
  76.      * DriverType driverType - these are defined in
  77.      */
  78.     kPluginNamePString,                        /* Name of hardware */
  79.     kVersionMajor, kVersionMinor,            /* NumVersion version */
  80.     kVersionStage, kVersionNonRel,
  81.  
  82.     /*
  83.      * DriverOSRuntime driverOSRuntimeInfo
  84.      */
  85.     0                                        /* RuntimeOptions driverRuntime            */
  86.     | (1 * kDriverIsLoadedUponDiscovery)    /* Loader runtime options                */
  87.     | (0 * kDriverIsOpenedUponLoad)            /* Opened when loaded                    */
  88.     | (1 * kDriverIsUnderExpertControl)        /* I/O expert handles loads/opens        */
  89.     | (0 * kDriverIsConcurrent)                /* Not concurrent yet                    */
  90.     | (0 * kDriverQueuesIOPB),                /* Not internally queued yet            */
  91.     kPluginNamePString,                        /* Str31 driverName    (OpenDriver param)    */
  92.     0, 0, 0, 0, 0, 0, 0, 0,                    /* UInt32 driverDescReserved[8]            */
  93.  
  94.     /*
  95.      * DriverOSService Information. This section contains a vector count followed by
  96.      * a vector of structures, each defining a driver service.
  97.      */
  98.     1,                                        /*     ServiceCount nServices                */
  99.  
  100.     /*
  101.      * DriverServiceInfo service[0]
  102.      */
  103.     kServiceCategoryPCCard,                    /* OSType serviceCategory                */
  104.     kServiceTypePCCardEnabler,                /* OSType serviceType                    */
  105.  
  106.     1, 0,developStage, 1                    /* version of the Open Transport         */
  107.                                             /* programming interface that this        */
  108.                                             /* driver supports                        */
  109.                                             /* should be kOTDriverAPIVersion        */
  110. };
  111.  
  112.  
  113. // --------------------
  114. // Here's the exported Plugin Function Table…
  115. PCCardEnablerPluginDispatchTable ThePluginDispatchTable =
  116. {
  117.     /* PCCardEnablerPluginHeader */
  118.     { kPCCardEnablerPluginCurrentVersion, 0, 0, 0 },
  119.  
  120.     /* CEValidateHardwareProc            */        MyValidateHardware,
  121.     /* CEInitializeProc                    */    CEInitializeCard,
  122.     /* CECleanupProc                    */    CEFinalizeCard,
  123.     /* CEPowerManagementProc            */    CEPowerManagement,
  124.  
  125.     /* CEHandleEventProc                */    CEHandleCardEvent,
  126.     /* CEGetCardInfoProc                */    CEGetCardInfo,
  127.     /* CEAddCardPropertiesProc            */    CEAddCardProperties,
  128.     /* CEGetDeviceCountProc                */        MyGetDeviceCount,
  129.  
  130.     /* CEGetDeviceNameProc                */    CEGetDeviceName,
  131.     /* CEGetDeviceCompatibleNameProc    */    CEGetDeviceCompatibleNames,
  132.     /* CEGetDeviceTypeProc                */        MyGetDeviceType,
  133.     /* CEGetDeviceTypeNameProc            */    CEGetDeviceTypeName,
  134.     /* CEAddDevicePropertiesProc        */    CEAddDeviceProperties,
  135.     /* CEConfigureDeviceProc            */    CEConfigureDevice,
  136.     /* CEFinalizeDeviceProc                */    CEFinalizeDevice,
  137.  
  138.     /* CEValidateCISProc                */    CEValidateCIS,
  139.     /* CEGetFirstTupleProc                */        MyGetFirstTuple,
  140.     /* CEGetNextTupleProc                */    CSGetNextTuple,
  141.  
  142.     /* InterruptHandler                    */    CEDefaultInterruptHandler,
  143.     /* InterruptEnabler                    */    NULL,
  144.     /* InterruptDisabler                */    NULL
  145. };
  146.  
  147. #pragma export off
  148.  
  149. //----------------------------------------------------------------------
  150. //    Determine whether the plugin can support this card. 
  151. //  Returning noErr means that the card is supported
  152. OSStatus MyValidateHardware(const RegEntryRef *lpCardEntry)
  153. {
  154.     OSStatus             err;
  155.     
  156.     if (!(lpCardEntry)) return(paramErr);
  157.  
  158.     // see if we are supposed to handle this card, set global card id
  159.     err = _IdentifyCard(lpCardEntry, &gThisCardID);
  160.  
  161. #ifdef DEBUG_ON
  162.     if (err == noErr) DebugStr("\pCardWizard will handle this card!;g");
  163. #endif
  164.     return(err);
  165. }
  166.  
  167.  
  168. //----------------------------------------------------------------------
  169. //    Look to see if this is a card we are supposed to handle
  170. //    If it is return noErr, other wise return kUnsupportedCardErr
  171. OSStatus _IdentifyCard(const RegEntryRef *lpCardEntry, SupportedCardIDPtr lpCardType)
  172. {
  173.     PCCardTupleIterator        iter;
  174.     OSStatus                err = noErr;
  175.     unsigned char             tuple[MAX_TUPLE_SIZE];
  176.     UInt32                    size, manfID, socket, device;
  177.     Byte                    foundTuple;
  178.     
  179.     if(!(lpCardEntry  && lpCardType)) return(paramErr);
  180.  
  181.     // assume the card is unsupported
  182.     *lpCardType = kUnsupportedCardID;
  183.     
  184.     err =  CEGetSocketAndDeviceFromRegEntry(lpCardEntry, &socket, &device);
  185.     if (err != noErr)
  186.         return(err);                            
  187.  
  188.     iter = PCCardNewTupleIterator();
  189.     if (iter == NULL)
  190.         return memFullErr;
  191.  
  192.     // get the MANFID form the tuples
  193.     size = sizeof(UInt32);
  194.     err = CSGetFirstTuple(socket, device, iter, CISTPL_MANFID, &manfID, &size, &foundTuple);
  195.  
  196.     // if the MANFID matches, then verify it is the card we want
  197.     switch(manfID)
  198.     {
  199.         case kDaynaManfID:
  200.             // this is a Dayna card. See which one...
  201.             size = MAX_TUPLE_SIZE;
  202.             err = CSGetFirstTuple(socket, device, iter, CISTPL_VERS_1, tuple, &size, &foundTuple);
  203.  
  204.             if(err == noErr)
  205.                 if (CheckVers1Tuple(tuple, "Dayna Communications, Inc.", "CommuniCard E"))
  206.                     *lpCardType = kDaynaCommunicardEthernetAdapter;
  207.             break;
  208.  
  209.         case kMegahertzManfID:
  210.             // this is a Megahertz card. See which one...
  211.             size = MAX_TUPLE_SIZE;
  212.             err = CSGetFirstTuple(socket, device, iter, CISTPL_VERS_1, tuple, &size, &foundTuple);
  213.  
  214.             if(err == noErr)
  215.                 if (CheckVers1Tuple(tuple, "MEGAHERTZ", "CC3144"))
  216.                     *lpCardType = kMegahertzGoldSeries14_4FaxModem;
  217.             break;
  218.  
  219.     }
  220.  
  221.     (void) PCCardDisposeTupleIterator(iter);
  222.     // return whether or not we support the card
  223.     if (*lpCardType == kUnsupportedCardID)
  224.         return(kUnsupportedCardErr);
  225.     else                            
  226.         return(noErr);                            
  227. }
  228.  
  229.  
  230. //----------------------------------------------------------------------
  231. // no need for this yet, so just call the default
  232. OSStatus MyGetDeviceCount(const RegEntryRef * lpParentID, UInt32 *lpCount)
  233. {
  234.     OSStatus        retval;
  235.  
  236.     if (!(lpCount && lpParentID)) return(paramErr);
  237.     
  238.     retval = CEGetDeviceCount(lpParentID, lpCount);
  239.  
  240.     return(retval);
  241. }
  242.  
  243.  
  244. //----------------------------------------------------------------------
  245. // The Megahertz card needs to override the GetDeviceType
  246. OSStatus MyGetDeviceType(const RegEntryRef * lpDevice,UInt32 socket,UInt32 device,PCDeviceType *lpDeviceType)
  247. {
  248.     OSStatus         err;
  249.     
  250.     if (!(lpDevice && lpDeviceType)) return(paramErr);
  251.     
  252.     // see if we need to override the get device type
  253.     switch (gThisCardID)
  254.     {
  255.         case kMegahertzGoldSeries14_4FaxModem:
  256.             *lpDeviceType = kSerialDeviceType;
  257.             DebugMessage("\pMegahertz Gold override GetDeviceType;g");
  258.             return (noErr);
  259.             break;
  260.     }
  261.  
  262.     // this call was not overridden, so call the default behavior
  263.     err = CEGetDeviceType(lpDevice, socket, device, lpDeviceType);
  264.  
  265.     return(err);
  266. }
  267.  
  268.  
  269. //----------------------------------------------------------------------
  270. // The Megahertz card needs to override the CISTPL_FUNCID tuple
  271. // The Dayna card needs to override the CISTPL_FUNCE tuple
  272. // REVIEW: we should set foundTuple and make sure the buffersize is big enough
  273. OSStatus MyGetFirstTuple(UInt32 socket, UInt32 device,            
  274.                                 PCCardTupleIterator lpTupleIterator,
  275.                                 Byte desiredTuple,             
  276.                                 void *lptupleData,
  277.                                 UInt32 *lpTupleBufferSize,
  278.                                 Byte *lpFoundTuple)
  279. {
  280.     OSStatus                 err = noErr;
  281.     unsigned char            *dataPtr = (unsigned char *)lptupleData;
  282.                         
  283.     if(!(lpTupleIterator && lpFoundTuple && dataPtr && *lpTupleBufferSize))
  284.         return(paramErr);
  285.     
  286.     // see if we need to override for a specific card and tuple type
  287.     switch(gThisCardID)
  288.     {
  289.         case kDaynaCommunicardEthernetAdapter:
  290.             if(desiredTuple == CISTPL_FUNCE)
  291.             {
  292.                 // fake an ethernet FUNCE (page 52  of metaformat spec)
  293.                 dataPtr[0] = 0x01;        // LAN_TECH
  294.                 dataPtr[1] = 0x02;        // ethernet
  295.                 dataPtr[2] = 0xFF;
  296.                 DebugMessage("\pDayna Communicard E override GetFirstTuple;g");
  297.                 *lpTupleBufferSize = 3;    
  298.                 return (noErr);                
  299.             }
  300.             break;
  301.  
  302.         case kMegahertzGoldSeries14_4FaxModem:
  303.             if(desiredTuple == CISTPL_FUNCID)
  304.             {
  305.                 // fake a serial FUNCID
  306.                 dataPtr[0] = 0x02;
  307.                 dataPtr[1] = 0x00;
  308.                 *lpTupleBufferSize = 2;    
  309.                 DebugMessage("\pMegahertz Gold override GetFirstTuple;g");
  310.                 return (noErr);                
  311.             }
  312.             break;
  313.     }
  314.     
  315.     // this call was not overridden, so call the default behavior
  316.     err = CSGetFirstTuple(socket, device,lpTupleIterator,desiredTuple,
  317.                                 lptupleData,lpTupleBufferSize,lpFoundTuple);
  318.     
  319.     return(err);
  320. }                        
  321.  
  322.  
  323. //----------------------------------------------------------------------
  324. //     Pass in a VERS1 tuple and check that the manufacturer name and card name are
  325. // the the same as the ones passed in
  326. Boolean CheckVers1Tuple(unsigned char * data, char * manufacturerName, char * cardName)
  327. {
  328.     unsigned char          *ptr;
  329.  
  330.     // the manufacturer name is a null terminated string starting in byte three
  331.     ptr = &(data[2]);
  332.     if(CStrCmp((const char *) ptr, manufacturerName) == 0)
  333.     { 
  334.         // the card name is a null terminated string that starts after the manufacturer name
  335.         while(*ptr++)
  336.             ;
  337.         if(CStrCmp((const char *) ptr, cardName) != 0)
  338.             return(false);
  339.     }
  340.     else
  341.         return(false);                            
  342.     
  343.     // if we make it to here, both names match
  344.     return(true);
  345. }
  346.  
  347.